<template>
	<view class="content">
		<u-overlay :show="share_qrcode_flag" @click="share_qrcode_flag = false" :zoom="false" :custom-style="{ background: 'rgba(0,0,0,.8)' }" :duration="0">
			<view class="sq_box">
				<view class="tz_box qrcode_box">
					<view class="btn" @click="saveShareImg(canvasToTempFilePath)">
						保存图片
					</view>
					<!-- <view class="close_box" @click="share_qrcode_flag = false"><u-icon name="close" color="#ffffff"></u-icon></view> -->
					<view class="share_qrcode">
						<canvas canvas-id="myCanvas" style="width: 690px;height:1040px; position: fixed;top: -10000px;"></canvas>
						<image @longpress="showSaveImgWin = true" style="width: 100%; height: 100%;" :src="canvasToTempFilePath"></image>
					</view>
				</view>
			</view>
		</u-overlay>
		
		<u-modal
			v-model="showSaveImgWin"
			content="确定要保存图片吗"
			@confirm="saveShareImg(canvasToTempFilePath)"
			@cancel="showSaveImgWin = false"
			:show-cancel-button="true"
		></u-modal>
	</view>
</template>

<script>
export default {
	name: 'XQGeneratePoster',
	data() {
		return {
			ratio: 1,
			ctx: null, // 创建canvas对象
			canvasToTempFilePath: null, // 保存最终生成的导出的图片地址
			openStatus: true, // 声明一个全局变量判断是否授权保存到相册
			share_qrcode_flag: false,
			showSaveImgWin: false //保存图片到相册
		};
	},

	methods: {
		share_qrcode(option) {
			if (option) {
				if (!this.canvasToTempFilePath) {
					this.createCanvasImage(option);
				}
				this.share_qrcode_flag = true;
			}
		},

		//获取图片信息
		downloadFileImg(url) {
			return new Promise(resolve => {
				uni.getImageInfo({
					src: url,
					success: res => {
						resolve(res.path);
					},
					fail: err => {
						console.log(err);
						uni.showToast({
							title: '网络错误请重试',
							icon: 'loading'
						});
					}
				});
			});
		},
		// 生成海报
		async createCanvasImage(option) {
			// 点击生成海报数据埋点
			if (!this.ctx) {
				uni.showLoading({
					title: '生成中...'
				});
				let code = this.downloadFileImg(option.codeUrl);
				let cover = this.downloadFileImg(option.coverUrl);
				let headImg = this.downloadFileImg(option.headUrl);
				let bgUrl = '';
				if (option.bgUrl) {
					bgUrl = new Promise(resolve => {
						uni.downloadFile({
							//生成临时地址
							url: option.bgUrl,
							success: res => {
								resolve(res.tempFilePath);
							},
							fail: erros => {
								uni.showToast({
									title: '网络错误请重试',
									icon: 'loading'
								});
							}
						});
					});
				}
				Promise.all([headImg, code, cover, bgUrl]).then(result => {
					const ctx = uni.createCanvasContext('myCanvas', this);
					let canvasWidthPx = 640 * this.ratio,
						canvasHeightPx = 900 * this.ratio,
						avatarurl_width = 100, //绘制的头像宽度
						avatarurl_heigth = 100, //绘制的头像高度
						avatarurl_x = 40, //绘制的头像在画布上的位置
						avatarurl_y = 28, //绘制的头像在画布上的位置
						codeurl_width = 180, //绘制的二维码宽度
						codeurl_heigth = 180, //绘制的二维码高度
						codeurl_x = 70, //绘制的二维码在画布上的位置
						codeurl_y = 720, //绘制的二维码在画布上的位置
						coverurl_width = 610, //绘制的封面宽度
						coverurl_heigth = 350, //绘制的封面高度
						coverurl_x = 40, //绘制的封面在画布上的位置
						coverurl_y = 190; //绘制的封面在画布上的位置

					if (option.bgUrl) {
						ctx.drawImage(result[3], 0, 0, 690, 940); // 背景图片需要本地
					} else {
						//绘制圆角矩形
						ctx.save();
						ctx.translate(0, 0);
						//绘制圆角矩形的各个边
						this.drawRoundRectPath(ctx, 690, 940, 14);
						ctx.fillStyle = option.fillStyle || '#0688ff'; //若是给定了值就用给定的值否则给予默认值
						ctx.fill();
						ctx.restore();
					}

					// 白底
					ctx.setFillStyle('#ffffff');
					ctx.fillRect(25, 175, 640, 740);

					ctx.save(); // 先保存状态 已便于画完圆再用
					ctx.beginPath(); //开始绘制
					//先画个圆   前两个参数确定了圆心 （x,y） 坐标  第三个参数是圆的半径  四参数是绘图方向  默认是false，即顺时针
					ctx.arc(avatarurl_width / 2 + avatarurl_x, avatarurl_heigth / 2 + avatarurl_y, avatarurl_width / 2, 0, Math.PI * 2, false);
					ctx.clip(); //画了圆 再剪切  原始画布中剪切任意形状和尺寸。一旦剪切了某个区域，则所有之后的绘图都会被限制在被剪切的区域内
					ctx.drawImage(result[0], avatarurl_x, avatarurl_y, avatarurl_width, avatarurl_heigth); // 推进去图片

					ctx.restore(); //恢复之前保存的绘图上下文状态 可以继续绘制

					ctx.font = 'normal bold 45px sans-serif';
					ctx.setFillStyle('#ffffff'); // 文字颜色
					if (option.nickName) {
						this.dealWords({
							ctx: ctx, //画布上下文
							fontSize: 25, //字体大小
							word: option.nickName, //需要处理的文字
							maxWidth: 480, //一行文字最大宽度
							x: 190, //文字在x轴要显示的位置
							y: 40, //文字在y轴要显示的位置
							maxLine: 1 //文字最多显示的行数
						});
					}
					ctx.setFillStyle('#ffffff'); // 文字颜色
					ctx.setFontSize(25); // 文字字号
					ctx.fillText(option.miniName, 190, 130); // 绘制文字

					ctx.setFillStyle('#222222');
					if (option.tkName) {
						this.dealWords({
							ctx: ctx, //画布上下文
							fontSize: 32, //字体大小
							word: option.tkName, //需要处理的文字
							maxWidth: 610, //一行文字最大宽度
							x: 40, //文字在x轴要显示的位置
							y: 550, //文字在y轴要显示的位置
							maxLine: 2 //文字最多显示的行数
						});
					}

					ctx.font = 'normal normal 26px sans-serif';
					ctx.setFillStyle('#555555'); // 文字颜色
					ctx.fillText('', 40, 670); // 绘制文字

					ctx.font = 'normal normal 26px sans-serif';
					ctx.setFillStyle('#555555'); // 文字颜色
					if (option.tkAuthor) {
						this.dealWords({
							ctx: ctx, //画布上下文
							fontSize: 26, //字体大小
							word: option.tkAuthor, //需要处理的文字
							maxWidth: 490, //一行文字最大宽度
							x: 40, //文字在x轴要显示的位置
							y: 600, //文字在y轴要显示的位置
							maxLine: 1 //文字最多显示的行数
						});
					}

					// // 白底
					// ctx.setFillStyle('#CBE6FE');
					// ctx.fillRect(40, 690, 125, 40);

					// ctx.font = 'normal normal 24px sans-serif';
					// ctx.setFillStyle('#1F8DFE'); // 文字颜色
					// ctx.fillText(option.tkType, 78, 720); // 绘制文字

					// // 白底
					// ctx.setFillStyle('#FDE5D2');
					// ctx.fillRect(180, 690, 125, 40);

					// ctx.setFillStyle('#F37F26'); // 文字颜色
					// ctx.fillText(option.cost, 218, 720); // 绘制文字

					// // 白底
					// ctx.setFillStyle('#D2F1EF');
					// ctx.fillRect(320, 690, 125, 40);

					// ctx.setFillStyle('#2EBBB4'); // 文字颜色
					// ctx.fillText(option.isPub, 360, 720); // 绘制文字

					ctx.beginPath();
					// 设置线宽
					ctx.lineWidth = 1;
					// 设置间距（参数为无限数组，虚线的样式会随数组循环）
					ctx.setLineDash([10, 10]);
					// 移动画笔至坐标 x20 y20 的位置
					ctx.moveTo(30, 700);
					// 绘制到坐标 x20 y100 的位置
					ctx.lineTo(660, 700);
					// 填充颜色
					ctx.strokeStyle = '#aaaaaa';
					// 开始填充
					ctx.stroke();
					ctx.closePath();

					ctx.font = 'normal normal 36px sans-serif';
					ctx.setFillStyle('#E65449'); // 文字颜色
					ctx.fillText('长按识别', 300, 770); // 绘制孩子百分比

					ctx.font = 'normal normal 36px sans-serif';
					ctx.setFillStyle('#222222'); // 文字颜色
					ctx.fillText('二维码', 444, 770); // 绘制孩子百分比

					ctx.font = 'normal normal 36px sans-serif';
					ctx.setFillStyle('#222222'); // 文字颜色
					ctx.fillText('查看详细信息', 300, 820); // 绘制孩子百分比

					ctx.drawImage(result[2], coverurl_x, coverurl_y, coverurl_width, coverurl_heigth); // 绘制封面
					ctx.drawImage(result[1], codeurl_x, codeurl_y, codeurl_width, codeurl_heigth); // 绘制头像
					ctx.draw(false, () => {
						// canvas画布转成图片并返回图片地址
						uni.canvasToTempFilePath(
							{
								canvasId: 'myCanvas',
								width: 690,
								height: 940,
								destWidth: 690,
								destHeight: 940,
								success: res => {
									this.canvasToTempFilePath = res.tempFilePath;
									this.showShareImg = true;
									uni.showToast({
										title: '绘制成功'
									});
								},
								fail: err => {
									uni.showToast({
										title: '绘制失败'
									});
								},
								complete: () => {
									uni.hideLoading();
									uni.hideToast();
								}
							},
							this
						);
					});
				});
			}
		},

		drawRoundRectPath(cxt, width, height, radius) {
			cxt.beginPath(0);
			//从右下角顺时针绘制，弧度从0到1/2PI
			cxt.arc(width - radius, height - radius, radius, 0, Math.PI / 2);

			//矩形下边线
			cxt.lineTo(radius, height);

			//左下角圆弧，弧度从1/2PI到PI
			cxt.arc(radius, height - radius, radius, Math.PI / 2, Math.PI);

			//矩形左边线
			cxt.lineTo(0, radius);

			//左上角圆弧，弧度从PI到3/2PI
			cxt.arc(radius, radius, radius, Math.PI, (Math.PI * 3) / 2);

			//上边线
			cxt.lineTo(width - radius, 0);

			//右上角圆弧
			cxt.arc(width - radius, radius, radius, (Math.PI * 3) / 2, Math.PI * 2);

			//右边线
			cxt.lineTo(width, height - radius);
			cxt.closePath();
		},
		//处理文字多出省略号显示
		dealWords(options) {
			options.ctx.setFontSize(options.fontSize); //设置字体大小
			let allRow = Math.ceil(options.ctx.measureText(options.word).width / options.maxWidth); //实际总共能分多少行
			let count = allRow >= options.maxLine ? options.maxLine : allRow; //实际能分多少行与设置的最大显示行数比，谁小就用谁做循环次数
			let endPos = 0; //当前字符串的截断点
			for (let j = 0; j < count; j++) {
				let nowStr = options.word.slice(endPos); //当前剩余的字符串
				let rowWid = 0; //每一行当前宽度
				if (options.ctx.measureText(nowStr).width > options.maxWidth) {
					//如果当前的字符串宽度大于最大宽度，然后开始截取
					for (let m = 0; m < nowStr.length; m++) {
						rowWid += options.ctx.measureText(nowStr[m]).width; //当前字符串总宽度
						if (rowWid > options.maxWidth) {
							if (j === options.maxLine - 1) {
								//如果是最后一行
								options.ctx.fillText(nowStr.slice(0, m - 1) + '...', options.x, options.y + (j + 1) * 40); //(j+1)*18这是每一行的高度
							} else {
								options.ctx.fillText(nowStr.slice(0, m), options.x, options.y + (j + 1) * 40);
							}
							endPos += m; //下次截断点
							break;
						}
					}
				} else {
					//如果当前的字符串宽度小于最大宽度就直接输出
					options.ctx.fillText(nowStr.slice(0), options.x, options.y + (j + 1) * 40);
				}
			}
		},

		// 保存到系统相册
		saveShareImg(canvasToTempFilePath) {
			uni.saveImageToPhotosAlbum({
				filePath: canvasToTempFilePath,
				success: () => {
					this.$u.toast('保存成功，快去分享到朋友圈吧~');
				},
				fail: () => {
					this.$u.toast('保存失败~');
				}
			});
		}
	}
};
</script>

<style lang="scss">
.sq_box {
	display: flex;
	height: 100%;
	justify-content: center;
	color: #333333;
	padding: 60rpx;
	.tz_box {
		background-color: #ffffff;
		border-radius: 14rpx;
		padding: 40rpx;
		display: flex;
		flex-direction: column;
		align-items: center;
		position: relative;
		width: 100%;
		text-align: center;
		line-height: 50rpx;
		height: 75vh;
		.close_box {
			position: absolute;
			left: 50%;
			bottom: -100rpx;
			border: 4rpx solid #ffffff;
			width: 60rpx;
			height: 60rpx;
			margin-left: -30rpx;
			border-radius: 50%;
			display: flex;
			justify-content: center;
			align-items: center;
		}
		.btn{
			position: absolute;
			left: 50%;
			background: #F2E0BC;
			color: #333333;			
			bottom: -100rpx;
			// border: 4rpx solid #ffffff;
			width: 160rpx;
			height: 60rpx;
			border-radius: 10rpx;
			margin-left: -80rpx;
			display: flex;
			justify-content: center;
			align-items: center;
		}
		.share_qrcode {
			width: 100%;
			height: 100%;
		}
		.tz_title {
			font-size: 34rpx;
			font-weight: 600;
		}

		.content_box {
			margin: 50rpx 0;
			text-align: left;
			.inf {
				font-weight: bold;
				font-size: 36rpx;
				.copy {
					font-weight: 0;
					color: rgb(85, 104, 147);
					font-size: 30rpx;
				}
			}
		}
	}
	.qrcode_box {
		padding: 0;
	}
}
</style>
